package sg.edu.nus.iss.billing.model.calculation;

import java.util.ArrayList;
import java.util.List;

import sg.edu.nus.iss.billing.controller.TransactionController;
import sg.edu.nus.iss.billing.exceptions.ControllerException;
import sg.edu.nus.iss.billing.model.BaseModel;
import sg.edu.nus.iss.billing.model.bill.Bill;
import sg.edu.nus.iss.billing.model.bill.BillingPeriod;
import sg.edu.nus.iss.billing.model.charge.IChargable;
import sg.edu.nus.iss.billing.model.subscription.ISubscribable;
import sg.edu.nus.iss.billing.model.transaction.ServiceTransaction;

/**
 * @author Thurein, ZiFeng, YinNi
 */
public class PerTransaction extends BaseModel implements IChargeMethod {
	private static final long serialVersionUID = 1L;

	@Override
	public double calculate(IChargable fee, Bill chargingBill) {

		BillingPeriod billingPeriod = chargingBill.getBillingPeriod();
		List<ServiceTransaction> transactions = this.getTransactions(chargingBill.getBillingAccount().getAccountNo(),
				fee.getChargingService(), billingPeriod);

		return doCalculation(transactions, fee.getRate().getAmount());

	}

	public double doCalculation(List<ServiceTransaction> transactions, double rate) {
		if (transactions == null)
			return 0;
		double amount = 0;
		for (ServiceTransaction transaction : transactions)
			amount = amount + transaction.getDurationOfCall() * rate;

		return Math.round(amount * 100.00) / 100.00;// round decimal 2 point
	}

	private List<ServiceTransaction> filterTransactionsByService(List<ServiceTransaction> transactions,
			ISubscribable service) {
		List<ServiceTransaction> result = new ArrayList<ServiceTransaction>();
		for (ServiceTransaction serviceTransaction : transactions)
			if (serviceTransaction.getServiceType().name().equals(service.getServiceId()))
				result.add(serviceTransaction);
		return result;
	}

	private List<ServiceTransaction> getTransactions(String AccountNo, ISubscribable service,
			BillingPeriod billingPeriod) {
		
		TransactionController transactionController = new TransactionController();
		try {
			List<ServiceTransaction> transactions = transactionController.getServiceTransaction(AccountNo,
					billingPeriod);
			if (transactions != null)
				return this.filterTransactionsByService(transactions, service);
			else
				return new ArrayList<ServiceTransaction>();
		} catch (ControllerException e) {
			e.printStackTrace();
			return null;
		}
	}
}
